//Path: ISPD_Contest/sizer-v1.0

#ifndef _GRAPHMODEL_H
#define _GRAPHMODEL_H

#include <vector>
#include <string>
#include <list>
#include <map>
#include <utility>

// Boost Library Headers

#include <boost/config.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/utility.hpp>


// Enum Node Type

enum gateType_t  { PrimaryInput, PrimaryOutput, Combinational, Sequential } ;
enum pinDirection_t { Input, Output } ;

struct gateProperty ;
struct netProperty ;


typedef boost::property < boost::graph_name_t,  std::string > graphProperties;

typedef boost::adjacency_list <boost::listS, boost::vecS, boost::bidirectionalS, 
        gateProperty, netProperty, graphProperties > boostGraph ;

typedef boost::graph_traits<boostGraph>::vertex_descriptor vertex_descriptor ;

typedef boost::graph_traits<boostGraph>::edge_descriptor   edge_descriptor ;

struct netConnectivity {
        std::string                    netName ;
        vertex_descriptor              sourceVertex ;
        std::pair<string, string>      sourceDir; //Min
        std::vector<vertex_descriptor> targetVertices ;
        std::string                    sourcePin ;
        std::vector<std::string>       targetPins ;
        std::vector<std::pair<string, string> > targetDirs ; //Min
} ;


struct GateDelayStructure
{
	std::string  cellName ;
	double 		 avgDelay ;
	double 		 leakagePower ;
} ;

struct DelayComparison
{
	bool operator()(const GateDelayStructure& i, const GateDelayStructure& j)
	{
		return i.avgDelay < j.avgDelay ;
	}
};


struct gateProperty {
        
        std::string footPrint ;
        std::string instanceName ;
        std::string cellName;
        std::string tempCellName;
        
        double Slew_Violation;
        double Slack_Violation;
        double Cap_Violation;
        
        double Slew_Redundancy;
        double Slack_Redundancy;
        double Cap_Redundancy;
        
        // used for Primary Outputs
	double outCapacitance ;
        double min;
        double max;
        
        // used for Primary Inputs (rise, fall)
	std::pair<double, double>   arrivalTime ;
	std::pair<double, double>   slewTime ;

        gateType_t  gateType ;

        int gate_idx;
        int dff_id;
        int topo_id;
        int visited;
        int degree_count;
        
        std::vector < std::string >  noCapViolationCells ;
        std::vector < GateDelayStructure > sortedNoCapViolation ;
		
        int previousIndex ;
		
        std::vector < vertex_descriptor > faninDFFs ;
        
	double  maxOutCapacitance ;
	double	minOutCapacitance ;
        double  lessSharing;
        //int source_gate_id;
        //std::vector<int> target_gate_ids;                      
        
        // Stores the cell name of Standard Cell Library          
        std::vector < std::string > listOfCells ;
        std::vector < std::string > ReducedCellSet ;
		
        double minDelayLeakage ;
        double maxDelayLeakage ;
        double minDelayAvg ;
        double maxDelayAvg ;
        
        // Stores mapPinNet["pin_name"] = pinDirection_t           
        std::map < std::string, std::pair<std::string, pinDirection_t> > mapPinNetDirection;
     
        int level ;
        int distance ;
        int touched;
        int fixed;
        bool isFixed ;
	
        std::map<std::string, double>  minFallTransition ;
	std::map<std::string, double>  maxFallTransition ;
	std::map<std::string, double>  minRiseTransition ;
	std::map<std::string, double>  maxRiseTransition ;

} ;


struct netProperty {

        std::string netName ;
                
        // The parasitic load extracted from .sepf file                                                                                                                                              
        double netParasiticLoad ;
        
        std::string sourcePinName ;
        std::string targetPinName ;
        
        double  riseArrivalTime ;
	double  fallArrivalTime ;
	
	double  riseTransition ;
	double  fallTransition ;
	
	bool    isProcessed;
	
	netProperty() {isProcessed = false;} 

} ;


#endif
